#include "losu.h"
#include "losu_bytecode.h"
#include "losu_dump.h"
#include "losu_gc.h"
#include "losu_mem.h"
#include "losu_object.h"
#include "losu_syntax.h"
#include "losu_vm.h"

#include "array.h"
#include "../xkit.h"
#include "collections.h"

static inline int32_t __xkit_arg_returnAny(losu_vm_t vm, losu_object_t o) {
    stack_push(vm, *o);
    return 1;
}

/** losu-capi (self, size: number) -> self
 * @brief: "constructor of class: THISxkit_MODULEcollections_CLASSArray"
 */
int32_t THISxkit_MODULEcollections_CLASSArray_constructor(losu_vm_t vm, int32_t argc, losu_object argv[]) {
    if (argc < 2) {
        __error_TooFewArguments(vm);
        return 0;
    }
    ArrayHeader *h = NULL;
    size_t size = obj_getnum(vm, argv + 1);
    h = ArrayInit(vm, size);
    if (h) {
        obj_unitsetstr(vm, *argv, "__cptr__", obj_newptr(vm, (void*)h));
    }
    return __xkit_arg_returnAny(vm, argv);
}


/** losu-capi (self) -> number
 * @brief: "返回数组的固定大小"
 */
int32_t THISxkit_MODULEcollections_CLASSArray_FUNCsize(losu_vm_t vm, int32_t argc, losu_object argv[]) {
    (void)argc;
    (void)argv;
    ArrayHeader *h = getCPointer(vm, argv);
    return arg_returnNum(vm, h->length);
}


/** losu-capi (self, ... number) -> any
 * @brief: "返回指定索引的元素,越界引发OutOfIndex错误"
 */
int32_t THISxkit_MODULEcollections_CLASSArray_FUNCget(losu_vm_t vm, int32_t argc, losu_object argv[]) {
    if (argc < 2) {
        __error_TooFewArguments(vm);
        return 0;
    }
    ArrayHeader *h = getCPointer(vm, argv);
    int32_t i = 1;
    for (; i < argc; i ++) {
        size_t index = obj_getnum(vm, argv + i);
        losu_object target;
        if (ArrayGet(vm, h, index, &target)) {
            stack_push(vm, target);
        }
    }
    return i - 1;
}


/** losu-capi (self, item: any) -> self
 * @brief: "将数组的所有元素设置为指定值"
 */
int32_t THISxkit_MODULEcollections_CLASSArray_FUNCfill(losu_vm_t vm, int32_t argc, losu_object argv[]) {
    if (argc < 2) {
        __error_TooFewArguments(vm);
        return 0;
    }
    ArrayHeader *h = getCPointer(vm, argv);
    ArrayFill(vm, h, argv+1);
    return __xkit_arg_returnAny(vm, argv);
}


/** losu-capi (self) -> 
 * @brief: "析构函数"
 */
int32_t THISxkit_MODULEcollections_CLASSArray_FUNC__del__(losu_vm_t vm, int32_t argc, losu_object argv[]) {
    (void)argc;
    (void)argv;
    ArrayHeader *h = getCPointer(vm, argv);
    ArrayFree(vm, h);
    obj_unitsetstr(vm, *argv, "__cptr__", obj_newfalse(vm));
    return 0;
}


/** losu-capi (self, index: number, item: any) -> self
 * @brief: "设置指定索引的元素,越界引发OutOfIndex错误"
 */
int32_t THISxkit_MODULEcollections_CLASSArray_FUNCset(losu_vm_t vm, int32_t argc, losu_object argv[]) {
    if (argc < 3) {
        __error_TooFewArguments(vm);
        return 0;
    }
    ArrayHeader *h = getCPointer(vm, argv);
    size_t index = obj_getnum(vm, argv + 1);
    ArraySet(vm, h, index, argv + 2);
    return __xkit_arg_returnAny(vm, argv);
}
